#include <Windows.h>
#include <stdio.h>
#include <conio.h>

#define MAX_TX_DATA_LEN	1024
#define MAX_RX_DATA_LEN	1024

HANDLE hCom;
COMMTIMEOUTS TimeOuts;
DCB dcb;
DWORD Rxlength;			//实际读取的字节数
DWORD Txlength;			//实际发送的字节数
char str[10] = { 0 };
int Key = {0};
char DataNum = 0;
char TxData[5] = { 0 };
wchar_t Com[5] = { 0 };
int com = 0;
int baudRate = 115200;
LPCWSTR a;

int main(void)
{
	int i = 0;
	printf("请输入端口号:");
	scanf_s("%d", &com);
	printf("请输入波特率:");
	scanf_s("%d", &baudRate);
	wsprintfW(Com, L"COM%d", com);
	hCom = CreateFile(
		Com,						//COM口
		GENERIC_READ|GENERIC_WRITE,	//允许读|写
		0,							//指定共享属性，由于串⼝不能共享，所以该参数必须为0
		NULL,
		OPEN_EXISTING,				//打开而不是创建
		FILE_ATTRIBUTE_NORMAL,		//属性描述，该值为FILE_FLAG_OVERLAPPED，表⽰使用异步I/O，该参数为0，表⽰同步I/O操作
		NULL
	);
	if (hCom == INVALID_HANDLE_VALUE)
	{
		printf("打开COM%d失败!\n",com);
		return FALSE;
	}
	else
	{
		printf("COM%d打开成功！\n",com);
	}

	SetupComm(hCom, MAX_RX_DATA_LEN, MAX_TX_DATA_LEN); //初始化端口(端口句柄，最大接收缓存长度，最大发送缓存长度)

	/*******************************超时设置*****************************/
	//设定读超时
	TimeOuts.ReadIntervalTimeout = MAXDWORD;	//读间隔超时
	TimeOuts.ReadTotalTimeoutMultiplier = 0;	//读时间系数
	TimeOuts.ReadTotalTimeoutConstant = 0;		//读时间常量

	//设定写超时
	TimeOuts.WriteTotalTimeoutMultiplier = 1;	//写时间系数
	TimeOuts.WriteTotalTimeoutConstant = 1;		//写时间常量

	SetCommTimeouts(hCom, &TimeOuts);			//设置超时

	/*******************************配置串⼝*****************************/
	GetCommState(hCom, &dcb);
	dcb.BaudRate = baudRate;	//波特率
	dcb.ByteSize = 8;			//8位
	dcb.Parity = NOPARITY;		//⽆奇偶校验位
	dcb.StopBits = ONESTOPBIT;	//⼀个停⽌位

	SetCommState(hCom, &dcb);


	while (TRUE)
	{
		if (_kbhit())
		{
			Key = _getch();
			//printf("%d\n", Key);
			if (Key == 224)
			{
				Key = _getch();
				//printf("%d\n", Key);
				if (Key == 72)		DataNum = 55;	//Up
				else if (Key == 80)	DataNum = 56;	//Down
				else if (Key == 77)	DataNum = 64;	//Right
				else if (Key == 75)	DataNum = 48;	//Left
				else if (Key == 83)	DataNum = 41;	//Delete
			}
			else if (Key == 13)	DataNum = 57;	//Enter
			else if (Key == 8)	DataNum = 49;	//Backspace
			else if (Key == 32)	DataNum = 40;	//Space
			else if (Key == 9)	DataNum = 8;	//Tab作为shift键
			else if (Key >= 'a' && Key <= 'e') DataNum = 3 + 8 * (Key - 'a');
			else if (Key >= 'f' && Key <= 'j') DataNum = 4 + 8 * (Key - 'f');
			else if (Key >= 'k' && Key <= 'o') DataNum = 5 + 8 * (Key - 'k');
			else if (Key >= 'p' && Key <= 't') DataNum = 6 + 8 * (Key - 'p');
			else if (Key >= 'u' && Key <= 'z') DataNum = 7 + 8 * (Key - 'u');
			else if (Key >= '1' && Key <= '3') DataNum = 46 + 8 * (Key - '1');
			else if (Key >= '4' && Key <= '6') DataNum = 45 + 8 * (Key - '4');
			else if (Key >= '7' && Key <= '9') DataNum = 44 + 8 * (Key - '7');
			else if (Key == '0')	DataNum = 63;

			sprintf_s(TxData, sizeof(TxData), "#%2d!", DataNum);
			if (DataNum < 10)	TxData[1] = '0';
			if (WriteFile(hCom, TxData, 4, &Txlength, NULL) == 0)
			{
				printf("串口发送失败!");
				printf("%d",GetLastError());
				return FALSE;
			}
		}
		if (ReadFile(hCom, str, sizeof(str), &Rxlength, NULL) == 0)
		{
			printf("串口读取失败!");
			printf("%d", GetLastError());
			return FALSE;
		}
		else if (Rxlength > 0)
		{
			for (i = 0; i < 10; i++)
			{
				printf("%c", str[i]);
			}
			printf("\n");
		}
		for (i = 0; i < 10; i++)
			str[i] = 0;
		PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR); //清空发送、接收缓冲区
		Sleep(20);
	}
	CloseHandle(hCom);	//使用句柄后都要清除句柄
}